/*
    KMC Simulation
    Copyright (c) 2012 Filip Rozbořil

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "KmcSettings.h"
#include "KmcSimulation.h"
#include "Utils.h"
#include "Exception.h"

#ifdef SEGF_DEBUG
#include <execinfo.h>
#include <signal.h>
void handler(int sig) 
{
	Utils::consolePrint("[MAIN][ERROR] Signal " + Utils::convertToString(sig));
	const int size = 100;
   void* buffer[size];

   int nptrs = backtrace(buffer, size);
   Utils::consolePrint("[MAIN] backtrace() returned " + Utils::convertToString(nptrs) + " addresses");

   char** strings = backtrace_symbols(buffer, nptrs);
   if (strings == NULL) 
   {
     	Utils::consolePrint("[MAIN] Failed to backtrack symbols");
   }
   else
   {
   	for (int i = 0; i < nptrs; i++)
			Utils::consolePrint(string(strings[i]));
        
  		free(strings);
	}
#ifdef DEBUG_FAST
   Utils::printBuffer();
#endif
  exit(1);
}
#endif



int main(int argc, char* argv[])
{
	cout 	<< "[Kinetic Monte Carlo]" << endl
 		<< "Version: " << KmcSimulation::Version << endl << endl;
 		
#ifdef SEGF_DEBUG
	signal(SIGSEGV, handler);
	signal(SIGBUS, handler);
#endif
	try
	{
		KmcSettings sett;
		cout 	<< "[Simulation settings]" << endl
			<< sett << endl;
			
		KmcSimulation kmc(sett);
		kmc.run();
		if(!kmc.isSuccess())
		{
			throw Exception("Simulation exceeded the maximum number of events");
		}
	}
	catch(Exception& e)
	{
	 	cout << "ERROR: " << e.what() << endl;
	 	return 1;
	}
	
#ifdef DEBUG_FAST
   Utils::printBuffer();
#endif

	return 0;
}
